package com.batdream.message.netty;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
import io.netty.handler.timeout.IdleStateHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @author Wang Chen Peng
 * @date 2018/12/24
 * describe:
 */
@Component
public class WorkerServiceHandle extends ChannelInitializer<SocketChannel> {

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        System.out.println("出现异常");
        cause.printStackTrace();
        //super.exceptionCaught(ctx, cause);
    }

    @Override
    protected void initChannel(SocketChannel socketChannel) throws Exception {
        ChannelPipeline channelPipeline = socketChannel.pipeline();

        //==================以下是对http协议的支持===============

        //基于http协议的编解码器
        channelPipeline.addLast("HttpServerCodec", new HttpServerCodec());
        //对写大数据流的支持
        channelPipeline.addLast("ChunkedWriteHandler", new ChunkedWriteHandler());
        //对http message进行聚合器 里面包括request response 传入一个最大消息的长度 几乎都会用到此
        channelPipeline.addLast("HttpObjectAggregator",new HttpObjectAggregator(1024*64));

        //==================以下是对心跳的支持===============

        /*
         * 针对客户端 如果在1分钟之内没有发送 读写心跳all 则主动断开
         * 针对读空闲 写空闲 则不做处理
         * 时间为了测试设置的秒数较低
         */
        channelPipeline.addLast("IdleStateHandler", new IdleStateHandler(5, 6, 15));

        HeartBeatHandler heartBeatHandler = new HeartBeatHandler();
        heartBeatHandler.init();
        channelPipeline.addLast("HeartBeatHandler",heartBeatHandler);

        /**
         * web socket服务器处理的协议 用于指定给客户端连接访问的路由 : /web-socket
         * 此handler会处理一些繁重复杂的事
         * 例如 握手动作 心跳动作 关闭等
         * 对于web socket来讲 都是以frames进行传输的 不同的数据类型对应的frames也不同
         */
        channelPipeline.addLast("WebSocketServerProtocolHandler", new WebSocketServerProtocolHandler("/ws"));
        //自定义的handler
        ChatHandler chatHandler = new ChatHandler();
        //初始化依赖
        chatHandler.init();

        channelPipeline.addLast("Custom", chatHandler);
    }
}
